# from Module.xRayDetection.ftp_function import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter,QPen,QBrush,QStandardItem,\
    QPixmap,QStandardItemModel,QMouseEvent,QPaintEvent
from PyQt5.QtCore import QRect,Qt

def show_text2(function):
    def wrapped(self, *args, **kwargs):
        if self.vars["showTextLock"]:
            self.vars["showTextLock"] = False
            result = function(self, *args, **kwargs)
            items = self.get_selected()
            l = len(items)    #选择了几个
            l_ = self.vars["listViewModel"].rowCount() - 1   #总
            if l_ != 0:
                if l == 0:
                    self.vars["listViewModel"].item(0).setCheckState(Qt.Unchecked)
                else:
                    self.vars["listViewModel"].item(0).setCheckState(Qt.PartiallyChecked)
                if l == l_: #如果总的等于选择的
                    self.vars["listViewModel"].item(0).setCheckState(Qt.Checked)
            self.vars["showTextLock"] = True
            self.vars["lineEdit"].setText("" if l == 0 else ";".join((item.text() for item in items)))
        else:
            result = function(self, *args, **kwargs)
        return result

    return wrapped


# if self.vars["listViewModel"].item(1).checkState() == Qt.Checked:
class QComboCheckBox_all(QComboBox):
    class MyListView(QListView):
        def __init__(self, parent: QWidget = None, vars=None):
            super().__init__(parent)
            self.vars = vars

        def mousePressEvent(self, event: QMouseEvent):
            self.vars["lock"] = False
            super().mousePressEvent(event)

        def mouseDoubleClickEvent(self, event: QMouseEvent):
            self.vars["lock"] = False
            super().mouseDoubleClickEvent(event)

    def __init__(self, device_ = None,parent: QWidget = None):
        super().__init__(parent)
        self.vars = dict()
        self.vars["lock"] = True
        self.vars["showTextLock"] = True
        # 装饰器锁，避免批量操作时重复改变lineEdit的显示
        self.vars["lineEdit"] = QLineEdit(self)
        self.vars["lineEdit"].setReadOnly(True)
        self.vars["listView"] = self.MyListView(self, self.vars)
        self.vars["listViewModel"] = QStandardItemModel(self)
        self.setModel(self.vars["listViewModel"])
        self.setView(self.vars["listView"])
        self.setLineEdit(self.vars["lineEdit"])
        self.activated.connect(self.__show_selected)
        self.AddDevice(device_)
    def AddDevice(self,device):
        self.clear()
        if device == [''] or device == '' or device == None:
            self.add_item("None")
            self.vars["listViewModel"].item(0).setCheckState(Qt.Checked)
            self.vars["lineEdit"].setText(self.vars["listViewModel"].item(0).text())
            self.data = 1
        else:
            self.data = len(device)
            if len(device) !=1:
                self.add_item("(全选)")
                self.data = len(device)+1
            for i in device:
                self.add_item(i)
            if len(device) == 1:
                self.vars["listViewModel"].item(0).setCheckState(Qt.Checked)
                self.vars["lineEdit"].setText(self.vars["listViewModel"].item(0).text())
    @show_text2
    def add_item(self, text: "str"):
        # 根据文本添加子项
        item = QStandardItem()
        item.setText(text)
        item.setCheckable(True)
        if text == 'cpu' or text == 'Cpu':
            item.setCheckState(Qt.Checked)
        self.vars["listViewModel"].appendRow(item)

    def __select_reverse(self, row: "int"):

        item = self.vars["listViewModel"].item(row)
        item.setCheckState(Qt.Unchecked if item.checkState() == Qt.Checked else Qt.Checked)

    @show_text2
    def select_all(self):
        # 全选
        for row in range(0, self.vars["listViewModel"].rowCount()):
            self.vars["listViewModel"].item(row).setCheckState(Qt.Checked)

    @show_text2
    def select_clear(self):
        # 全不选
        for row in range(0, self.vars["listViewModel"].rowCount()):
            self.vars["listViewModel"].item(row).setCheckState(Qt.Unchecked)

    def get_selected(self):
        # 获取当前选择的子项
        items = list()
        if self.data == 1:
            a = 0
        else:
            a = 1
        for row in range(a, self.vars["listViewModel"].rowCount()):
            item = self.vars["listViewModel"].item(row)
            if item.checkState() == Qt.Checked:
                items.append(item)
        return items

    def sort(self, order=Qt.AscendingOrder):
        # 排序，默认正序
        self.vars["listViewModel"].sort(0, order)

    @show_text2
    def __show_selected(self, index):
        if not self.vars["lock"]:
            if self.data != 1:
                if index == 0:
                    if self.vars["listViewModel"].item(0).checkState() == Qt.Checked:
                        self.select_clear()
                    else:
                        self.select_all()
                else:
                    self.__select_reverse(index)

                self.vars["lock"] = True
            else:
                self.__select_reverse(index)
                self.vars["lock"] = True


def show_text(function):
    def wrapped(self, *args, **kwargs):
        if self.vars["showTextLock"]:
            self.vars["showTextLock"] = False
            result = function(self, *args, **kwargs)
            items = self.get_selected()
            l = len(items)
            l_ = self.vars["listViewModel"].rowCount() - 1
            for item in items:
                if 'c' not in item.text() and 'C' not in item.text() :
                    self.vars["listViewModel"].item(0).setCheckState(
                        Qt.Checked if l == l_-1 else Qt.Unchecked if l == 0 else Qt.PartiallyChecked)
            self.vars["lineEdit"].setText("" if l == 0 else ";".join((item.text() for item in items)))
            if l == 0 and l_!=0:
                self.vars["listViewModel"].item(0).setCheckState(Qt.Unchecked)
            if l == 0 and l_==0:
                if self.vars["listViewModel"].item(0).checkState() == Qt.Checked:
                    self.vars["lineEdit"].setText(self.vars["listViewModel"].item(0).text())
                else:
                    self.vars["lineEdit"].setText('')
            else:
                self.vars["lineEdit"].setText("" if l == 0 else ";".join((item.text() for item in items)))
            self.vars["showTextLock"] = True
        else:
            result = function(self, *args, **kwargs)
        return result

    return wrapped


# if self.vars["listViewModel"].item(1).checkState() == Qt.Checked:
class QComboCheckBox(QComboBox):
    class MyListView(QListView):
        def __init__(self, parent: QWidget = None, vars=None):
            super().__init__(parent)
            self.vars = vars

        def mousePressEvent(self, event: QMouseEvent):
            self.vars["lock"] = False
            super().mousePressEvent(event)

        def mouseDoubleClickEvent(self, event: QMouseEvent):
            self.vars["lock"] = False
            super().mouseDoubleClickEvent(event)

    def __init__(self, parent: QWidget = None):
        super().__init__(parent)
        self.vars = dict()
        self.vars["lock"] = True
        self.vars["showTextLock"] = True
        # 装饰器锁，避免批量操作时重复改变lineEdit的显示
        self.vars["lineEdit"] = QLineEdit(self)
        self.vars["lineEdit"].setReadOnly(True)
        self.vars["listView"] = self.MyListView(self, self.vars)
        self.vars["listViewModel"] = QStandardItemModel(self)
        self.setModel(self.vars["listViewModel"])
        self.setView(self.vars["listView"])
        self.setLineEdit(self.vars["lineEdit"])
        self.activated.connect(self.__show_selected)

    def AddDevice(self,device):
        self.clear()
        if device == [''] or device == '' or device == None:
            self.add_item("CPU")
            self.vars["listViewModel"].item(0).setCheckState(Qt.Checked)
            self.vars["lineEdit"].setText(self.vars["listViewModel"].item(0).text())
            self.data = 1
        else:
            self.data = len(device)
            if len(device) !=1:
                self.add_item("(GPU全选)")
                self.data = len(device)+1
            for i in device:
                self.add_item(i)
            # if len(device) !=1:
            #     self.vars["listViewModel"].item(1).setCheckState(Qt.Checked)
            #     self.vars["lineEdit"].setText(self.vars["listViewModel"].item(1).text())
            if len(device) == 1:
                self.vars["listViewModel"].item(0).setCheckState(Qt.Checked)
                self.vars["lineEdit"].setText(self.vars["listViewModel"].item(0).text())
    @show_text
    def add_item(self, text: "str"):
        # 根据文本添加子项
        item = QStandardItem()
        item.setText(text)
        item.setCheckable(True)
        if text == 'cpu' or text == 'Cpu':
            item.setCheckState(Qt.Checked)
        self.vars["listViewModel"].appendRow(item)

    def __select_reverse(self, row: "int"):

        item = self.vars["listViewModel"].item(row)
        item.setCheckState(Qt.Unchecked if item.checkState() == Qt.Checked else Qt.Checked)
        if 'c' in item.text() or 'C' in item.text():  # 判断是不是点到了Cpu
            if item.checkState() == Qt.Checked:  # 如果现在Cpu是勾选的,就取消所有的其他勾选，只保留Cpu
                for i in range(self.data):
                    self.vars["listViewModel"].item(i).setCheckState(Qt.Unchecked)
                    item.setCheckState(Qt.Checked)
        if 'g' in item.text() or 'G' in item.text():  # 判断是不是点到了gpu
            if item.checkState() == Qt.Checked:
                self.vars["listViewModel"].item(1).setCheckState(Qt.Unchecked)

    @show_text
    def select_all(self):
        # 全选
        for row in range(2, self.vars["listViewModel"].rowCount()):
            self.vars["listViewModel"].item(row).setCheckState(Qt.Checked)
        self.vars["listViewModel"].item(0).setCheckState(Qt.Checked)
    @show_text
    def select_clear(self):
        # 全不选
        for row in range(2, self.vars["listViewModel"].rowCount()):
            self.vars["listViewModel"].item(row).setCheckState(Qt.Unchecked)
        self.vars["listViewModel"].item(0).setCheckState(Qt.Unchecked)
    def get_selected(self):
        # 获取当前选择的子项
        items = list()
        for row in range(1, self.vars["listViewModel"].rowCount()):
            item = self.vars["listViewModel"].item(row)
            if item.checkState() == Qt.Checked:
                items.append(item)
        return items

    def sort(self, order=Qt.AscendingOrder):
        # 排序，默认正序
        self.vars["listViewModel"].sort(0, order)

    @show_text
    def __show_selected(self, index):
        if not self.vars["lock"]:
            if self.data != 1:
                if index == 0:
                    if self.vars["listViewModel"].item(0).checkState() == Qt.Checked:
                        self.vars["listViewModel"].item(1).setCheckState(Qt.Unchecked)
                        self.select_clear()
                    else:
                        self.vars["listViewModel"].item(1).setCheckState(Qt.Unchecked)
                        self.select_all()
                else:
                    self.__select_reverse(index)

                self.vars["lock"] = True
            else:
                self.__select_reverse(index)
                self.vars["lock"] = True

